
package com.hlkj.pay.app.merchant.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.LocalContext;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.IMerchantDefaultConfigAppService;
import com.hlkj.pay.app.transfer.PayWayDoToResp;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.dto.LocalAdminUserRequest;
import com.hlkj.pay.dto.merchant.ProviderChannelFeeConfigList;
import com.hlkj.pay.dto.pay.PayWayQueryDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.infrastructure.model.merchant.DefaultFeeConfigDO;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.service.merchant.IMerchantDefaultConfigService;
import com.hlkj.pay.service.pay.IPayWayService;
import com.hlkj.pay.vo.ad.req.UpdateStatusReq;
import com.hlkj.pay.vo.merchant.resp.info.MerchantFeeConfigResp;
import com.hlkj.pay.vo.pay.resp.PayWayResp;

import cn.hutool.json.JSONConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/09/12 11:39
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Validated
public class MerchantDefaultConfigAppServiceImpl implements IMerchantDefaultConfigAppService {

    private final IMerchantDefaultConfigService merchantDefaultConfigService;

    private final IPayWayService payWayService;

    @Override
    public CommonResult<Void> delDefaultConfig(Long id) {
        log.info("delDefaultConfig id:{}", id);
        try {
            if (id == null) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            DefaultFeeConfigDO defaultFeeConfigDO = merchantDefaultConfigService.queryDetail(id);
            if (defaultFeeConfigDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            merchantDefaultConfigService.delDefaultConfig(id);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("delDefaultConfig error:{}", e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updateAdStatus(UpdateStatusReq updateStatusReq) {
        log.info("updateAdStatus updateStatusReq:{}", updateStatusReq);
        try {
            DefaultFeeConfigDO defaultFeeConfigDO = merchantDefaultConfigService.queryDetail(updateStatusReq.getId());
            if (defaultFeeConfigDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            merchantDefaultConfigService.updateAdStatus(updateStatusReq.getId(), updateStatusReq.getStatus());
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateAdStatus error:{}", e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<List<MerchantFeeConfigResp>> queryDefaultFeeConfig(Long id) {
        log.info("queryDefaultFeeConfig id:{}", id);
        try {
            Map<String, MerchantFeeConfigResp> merchantFeeConfigRespMap = new HashMap<>();
            if (id != null) {
                DefaultFeeConfigDO defaultFeeConfigDO = merchantDefaultConfigService.queryDetail(id);
                if (defaultFeeConfigDO == null) {
                    return CommonResult.success(Collections.emptyList());
                }
                if (StringUtils.hasText(defaultFeeConfigDO.getFeeConfig())) {
                    List<MerchantFeeConfigResp> providerChannelFeeConfigList = JsonUtils.parseArray(defaultFeeConfigDO.getFeeConfig(), MerchantFeeConfigResp.class);
                    merchantFeeConfigRespMap = providerChannelFeeConfigList.stream()
                            .collect(Collectors.toMap(providerChannel -> providerChannel.getPayWayCode(), Function.identity(), (t1, t2) -> t1));
                }
            }
            PayWayQueryDto payWayQueryDto = new PayWayQueryDto();
            List<PayWayDO> payWayList = payWayService.queryList(payWayQueryDto);

            List<MerchantFeeConfigResp> merchantFeeConfigResps = new ArrayList<>();
            Map<String, MerchantFeeConfigResp> finalMerchantFeeConfigRespMap = merchantFeeConfigRespMap;
            List<PayWayResp> payWayResps = PayWayDoToResp.INSTANCE.payWayRespList(payWayList);
            Map<String, PayWayResp> payMap = payWayResps.stream().collect(Collectors.toMap(payWayResp -> payWayResp.getCode(), Function.identity(), (t1, t2) -> t1));
            payWayList.stream().forEach(payWayDO -> {
                MerchantFeeConfigResp merchantFeeConfigResp = finalMerchantFeeConfigRespMap.get(payWayDO.getCode());
                if (merchantFeeConfigResp == null) {
                    merchantFeeConfigResp = new MerchantFeeConfigResp();
                    merchantFeeConfigResp.setPayWayCode(payWayDO.getCode());
                    merchantFeeConfigResp.setSeniorFeeType(payWayDO.getSeniorFeeType());
                    merchantFeeConfigResp.setApplyType(payWayDO.getApplyType());
                    merchantFeeConfigResp.setStepFeeType(payWayDO.getStepFeeType());
                }
                merchantFeeConfigResp.setPayWay(payMap.get(merchantFeeConfigResp.getPayWayCode()));
                merchantFeeConfigResps.add(merchantFeeConfigResp);
            });
            return CommonResult.success(merchantFeeConfigResps);
        }
        catch (Exception e) {
            log.error("delDefaultConfig error:{}", e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> saveDefaultFeeConfig(@Valid List<ProviderChannelFeeConfigList> providerChannelFeeConfigLists) {
        log.info("saveDefaultFeeConfig providerChannelFeeConfigList:{}", JsonUtils.toJsonString(providerChannelFeeConfigLists));
        try {
            if (CollectionUtils.isEmpty(providerChannelFeeConfigLists)) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            LocalAdminUserRequest localAdminUserRequest = (LocalAdminUserRequest) LocalContext.get();
            CommonEnum.SYS_TYPE sysType = CommonEnum.SYS_TYPE.from(localAdminUserRequest.getSysType());
            String sn = localAdminUserRequest.getSn();
            if(providerChannelFeeConfigLists.size()>5){
                localAdminUserRequest.setParams(null);
            }else {
                localAdminUserRequest.setParams(JsonUtils.toJsonString(providerChannelFeeConfigLists));
            }
            DefaultFeeConfigDO defaultFeeConfigDO = merchantDefaultConfigService.queryDetail(sysType.getCode(), localAdminUserRequest.getSn());
            JSONConfig jsonConfig = new JSONConfig();
            jsonConfig.setIgnoreNullValue(true);
            if (defaultFeeConfigDO == null) {
                // 新增
                defaultFeeConfigDO = new DefaultFeeConfigDO();
                defaultFeeConfigDO.setSnType(sysType.getCode());
                defaultFeeConfigDO.setSn(sn);
                defaultFeeConfigDO.setFeeConfig(JsonUtils.toJsonStr(providerChannelFeeConfigLists, jsonConfig));
                merchantDefaultConfigService.addFeeConfig(defaultFeeConfigDO);
            }
            else {
                defaultFeeConfigDO.setFeeConfig(JsonUtils.toJsonStr(providerChannelFeeConfigLists, jsonConfig));
                merchantDefaultConfigService.updateFeeConfig(defaultFeeConfigDO);
            }
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("delDefaultConfig error:{}", e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

}
